package controllers

import (
	"SuNing/md5"
	"SuNing/models"
	"SuNing/res"
	beego "github.com/beego/beego/v2/server/web"
	"strconv"
	"time"
)

type UserControllers struct {
	beego.Controller
}
type Json struct {
	Code int         `json:"code"`
	Msg  string      `json:"msg"`
	Data interface{} `json:"date"`
}

func (c *UserControllers) Login() {

	//获取用户输入
	username := c.GetString("username")
	password := c.GetString("password")
	// 验证用户名格式
	if !res.IsValidUsername(username) {
		c.Data["json"] = Json{
			Code: 400,
			Msg:  "用户名格式不正确：4-20个字符，且首字符必须是字母",
			Data: nil,
		}
		c.ServeJSON()
		return
	}
	// 验证密码格式：8-16位，不能包含特殊字符
	if !res.IsValidPassword(password) {
		c.Data["json"] = Json{
			Code: 400,
			Msg:  "密码格式不正确：8-16个字符，不能包含特殊字符",
			Data: nil,
		}
		c.ServeJSON()
		return
	}
	//检查用户是否被锁定
	lockKey := "lock-" + username
	num, _ := models.Rdb.Exists(lockKey).Result()
	if num > 0 {
		c.Data["json"] = Json{
			Code: 423,
			Msg:  "账号已锁定,1天后后解锁",
			Data: nil,
		}
		c.ServeJSON()
		return
	}
	//查询数据库检查用户名
	var user models.User
	//IsValidUsername := res.IsValidUsername(username)
	err := models.Db.Where("username=?", username).First(&user).Error
	if err != nil {
		c.Data["json"] = Json{
			Code: 500,
			Msg:  "账号错误",
			Data: nil,
		}
		c.ServeJSON()
		return
	}
	//验证密码

	if user.Password == md5.Md5(password) {
		// 登录成功，清除错误计数和锁定
		models.Rdb.Del(lockKey)
		countKey := "count-" + username
		models.Rdb.Del(countKey) // 登录成功后删除错误计数
		c.Data["json"] = Json{
			Code: 200,
			Msg:  "登录成功",
			Data: nil,
		}
		c.ServeJSON()
		return
	} else { //处理密码错误次数
		countKey := "count-" + username
		countStr, _ := models.Rdb.Get(countKey).Result()
		count, _ := strconv.Atoi(countStr)
		if count >= 2 { // 小于2次错误允许继续登录，3次及以上锁定
			models.Rdb.Set(lockKey, "locked", 24*time.Hour)
			c.Data["json"] = Json{
				Code: 423, // 或者使用429表示锁定状态
				Msg:  "账号已锁定,1天后后解锁",
				Data: nil,
			}
			c.ServeJSON()
			return
		}
		models.Rdb.Incr(countKey) //+1
		models.Rdb.Expire(countKey, 24*time.Hour)
		c.Data["json"] = Json{
			Code: 500,
			Msg:  "密码错误",
			Data: nil,
		}
		c.ServeJSON()
		return
	}

}
